# 添加核验类 =============================================
import requests
import urllib.parse
import json
import hashlib
import time
import pandas as pd  # 添加 pandas 导入
import os
# 在文件顶部添加
import logging
logging.basicConfig(
    filename='verification.log',
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s: %(message)s'
)

class AliYunIdVerifier:
    def __init__(self, app_code):
        self.app_code = app_code
        self.base_url = "https://kzidcardv1.market.alicloudapi.com/api-mall/api/id_card/check"
        self.headers = {
            "Authorization": f"APPCODE {app_code}",
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
        }

    def verify_id_name(self, name, id_card):
        data = {
            "name": name,
            "idcard": id_card
        }
        
        try:
            logging.info(f"开始核验 姓名：{name} 身份证：{id_card}")
            # 使用POST请求并编码请求体
            response = requests.post(
                self.base_url,
                data=data,
                headers=self.headers,
                timeout=5
            )
            
            # 记录完整请求详情
            logging.info(f"请求参数：{data}\nHTTP状态码：{response.status_code}")
            result = response.json()
            logging.info(f"请求参数：{data}\nHTTP结果：{result}")
            # 根据示例响应调整成功判断逻辑
            return (result.get("code") == 200), result
        except Exception as e:
            error_msg = f"接口请求异常: {str(e)}"
            logging.error(f"请求失败 - {error_msg}\n响应内容：{response.text if response else '无响应'}")
            return False, {"error": error_msg}

# 保留后续的文件选择功能和GUI类 =============================================
import tkinter as tk
from tkinter import filedialog
from tkinter import ttk
from concurrent.futures import ThreadPoolExecutor  # 添加线程池导入

def select_input_file():
    """选择输入文件对话框"""
    root = tk.Tk()
    root.withdraw()
    file_path = filedialog.askopenfilename(
        title="选择待核验文件",
        filetypes=[("Excel文件", "*.xlsx"), ("所有文件", "*.*")]
    )
    return file_path if file_path else None

def select_output_file():
    """选择输出文件对话框"""
    root = tk.Tk()
    root.withdraw()
    file_path = filedialog.asksaveasfilename(
        title="保存核验结果",
        defaultextension=".xlsx",
        filetypes=[("Excel文件", "*.xlsx"), ("所有文件", "*.*")]
    )
    return file_path if file_path else None

# 新增GUI主界面 =============================================
class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("身份证核验系统 v1.0 正式版")#试用版正式版 试用版
        self.geometry("1000x600")  # 加宽窗口
        
        # 移除旧的APP_CODE初始化
        self.create_widgets()

    def create_widgets(self):
        """创建界面控件"""
        # 顶部控制区域
        control_frame = tk.Frame(self)
        control_frame.pack(pady=10, fill=tk.X)
        
        # APPCODE输入框
        tk.Label(control_frame, text="APP_CODE:").pack(side=tk.LEFT)
        self.appcode_entry = tk.Entry(control_frame, width=30)
        self.appcode_entry.pack(side=tk.LEFT, padx=5)
        self.appcode_entry.insert(0, "YOUR_APP_CODE_HERE")  # 默认提示

        # 按钮区域
        btn_frame = tk.Frame(control_frame)
        btn_frame.pack(side=tk.RIGHT)
        
        self.import_btn = tk.Button(btn_frame, text="导入Excel", command=self.import_excel)
        self.import_btn.pack(side=tk.LEFT, padx=5)
        
        self.verify_btn = tk.Button(btn_frame, text="开始核验", state=tk.DISABLED, command=self.start_verify)
        self.verify_btn.pack(side=tk.LEFT, padx=5)
        
        self.export_btn = tk.Button(btn_frame, text="导出结果", state=tk.DISABLED, command=self.save_results)
        self.export_btn.pack(side=tk.LEFT, padx=5)
        
        # 新增清空按钮
        self.clear_btn = tk.Button(btn_frame, text="清空数据", command=self.clear_data)
        self.clear_btn.pack(side=tk.LEFT, padx=5)
        
        # 数据表格区域
        self.tree = ttk.Treeview(self, columns=('姓名', '身份证号', '是否匹配', '错误信息'), show='headings')
        self.tree.heading('姓名', text='姓名')
        self.tree.heading('身份证号', text='身份证号')
        self.tree.heading('是否匹配', text='是否匹配')
        self.tree.heading('错误信息', text='错误信息')
        self.tree.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
        
        # 进度条
        self.progress = ttk.Progressbar(self, orient=tk.HORIZONTAL, mode='determinate')
        self.progress.pack(fill=tk.X, padx=10, pady=5)
    
    def import_excel(self):
        expire_date = "2099-08-15"  # 设置过期日期 2023
        #判断当前时间是否过期
        if time.strftime("%Y-%m-%d") > expire_date:
            tk.messagebox.showerror("错误", "应用已过期，请联系管理员guofeifei@qq.com更新")
            return

        """导入Excel文件"""
        file_path = select_input_file()
        if file_path:
            self.load_data(file_path)
    
    def load_data(self, file_path):
        """加载数据到表格"""
        # 清空旧数据
        for i in self.tree.get_children():
            self.tree.delete(i)
            
        # 读取并展示数据
        df = pd.read_excel(file_path)
        for _, row in df.iterrows():
            self.tree.insert('', tk.END, values=(row['姓名'], row['身份证号']))
        
        self.verify_btn.config(state=tk.NORMAL)

    def start_verify(self):
        """执行核验的入口方法"""
        app_code = self.appcode_entry.get().strip()
        if not app_code or app_code == "YOUR_APP_CODE_HERE":
            tk.messagebox.showerror("错误", "请输入有效的APP_CODE")
            return
            
        # 初始化核验器（每次核验使用最新APP_CODE）
        self.verifier = AliYunIdVerifier(app_code)
        
        self.verify_btn.config(state=tk.DISABLED)
        self.export_btn.config(state=tk.DISABLED)
        self.progress['value'] = 0
        
        # 获取所有数据
        items = [self.tree.item(child)['values'] for child in self.tree.get_children()]
        
        # 使用线程池处理（修复方法绑定）
        with ThreadPoolExecutor() as executor:
            # 正确的方法绑定方式
            futures = [
                executor.submit(
                    self._verify_wrapper,  # 新增包装方法
                    item
                ) for item in items
            ]
            
            for i, future in enumerate(futures, 1):
                try:
                    result = future.result()
                    # 修复表格更新方式
                    item_id = self.tree.get_children()[i-1]
                    self.tree.item(item_id, values=result)  # 使用item方法更新数据
                except Exception as e:
                    print(f"核验出错: {str(e)}")
                finally:
                    self.progress['value'] = (i / len(futures)) * 100
                    self.update()
        
        self.verify_btn.config(state=tk.NORMAL)
        self.export_btn.config(state=tk.NORMAL)

    def _verify_wrapper(self, item):
        """线程安全的包装方法"""
        return self.verify_item(item)

    def verify_item(self, item):
        """修改返回结果处理"""
        name, id_card = item[0], item[1]
        is_match, detail = self.verifier.verify_id_name(name, id_card)
        
        # 获取desc字段
        desc = detail.get('data', {}).get('desc', '未知状态')
        return (
            name,
            id_card,
            f'{desc}',  # 在是否匹配列显示desc{"是" if is_match else "否"} ()
            detail.get('error', '') or detail.get('msg', '')
        )

    def save_results(self):
        """重命名并独立导出功能"""
        output_path = select_output_file()
        if output_path:
            try:
                data = [self.tree.item(child)['values'] for child in self.tree.get_children()]
                # 创建DataFrame时指定身份证号为字符串类型
                df = pd.DataFrame(data, columns=['姓名', '身份证号', '是否匹配', '错误信息'])
                df['身份证号'] = df['身份证号'].astype(str)  # 保留此转换
                
                # 添加文件覆盖检查
                if os.path.exists(output_path):
                    os.remove(output_path)
                
                df.to_excel(
                    output_path,
                    index=False,
                    engine='openpyxl'  # 移除dtype参数
                )
                tk.messagebox.showinfo("导出成功", f"文件已保存至：\n{output_path}")
            except Exception as e:
                tk.messagebox.showerror("导出失败", f"保存文件时出错：\n{str(e)}")
                logging.error(f"导出失败 - 路径：{output_path} 错误：{str(e)}")

    def clear_data(self):
        """清空所有数据"""
        # 删除表格所有行
        for item in self.tree.get_children():
            self.tree.delete(item)
        
        # 重置进度条
        self.progress['value'] = 0
        
        # 禁用功能按钮
        self.verify_btn.config(state=tk.DISABLED)
        self.export_btn.config(state=tk.DISABLED)
        
        tk.messagebox.showinfo("操作成功", "数据已清空")

# 更新使用示例 =============================================
if __name__ == "__main__":
    # 移除全局APP_CODE定义
    app = Application()
    app.mainloop()